package com.roberto.screens;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Buttons;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.InputMultiplexer;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.CheckBox;
import com.badlogic.gdx.scenes.scene2d.ui.SelectBox;
import com.badlogic.gdx.scenes.scene2d.ui.SelectionListener;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.roberto.main.Main;

/**
 * The main menu screen showing a background, the logo of the game and a label telling the user to touch the screen to start the game. Waits
 * for the touch and returns isDone() == true when it's done so that the ochestrating GdxInvaders class can switch to the next screen.
 * 
 */
public class MainMenu extends AbstractScreen {

    /** the SpriteBatch used to draw the background, logo and text **/
    private final SpriteBatch spriteBatch;
    /** the logo texture **/
    private final Sprite logo;
    /** the font **/
    private final BitmapFont font;
    /** is done flag **/
    private boolean isDone = false;
    private Stage stage;
    private Skin skin;
    private boolean options = false;
    private boolean canSelect = false;
    private Rectangle optionsCoordinates, playCoordinates, exitCoordinates;
    private Color optColour, playColour, exitColour;
    private int mouseY;
    private int mouseX;
    private OrthographicCamera camera;
    private Sprite[] sprite;
    private SelectBox selectBox;
    private CheckBox fsChecker, vsyncChecker, showFPS;
    private String play = "PLAY SPACE INVADERS";
    private String opt = "OPTIONS";
    private String exit = "EXIT";

    public MainMenu() {
        Main.pref.updateCFG();
        camera = new OrthographicCamera();
        camera.setToOrtho(false, Main.WIDTH, Main.HEIGHT);
        spriteBatch = new SpriteBatch();
        stage = new Stage(Main.WIDTH, Main.HEIGHT, false, spriteBatch);
        skin = new Skin(Gdx.files.internal("res/menu/uiskin.json"), Gdx.files.internal("res/menu/uiskin.png"));

        logo = new Sprite(Main.megaTexture, 112, 63, 144, 360);
        logo.rotate90(true);
        logo.setSize(360, 144);
        font = new BitmapFont(Gdx.files.internal("res/menu/kroe.fnt"), Gdx.files.internal("res/menu/kroe.png"), false);

        InputAdapter menuListener = new InputAdapter() {
            public boolean touchUp(int x, int y, int pointer, int button) {
                canSelect = button == Buttons.LEFT;
                return false;
            }
        };
        Gdx.input.setInputProcessor(new InputMultiplexer(menuListener, stage));

        createMenuTokens();
        createPTS();
        createOptionTokens();

    }

    private void createMenuTokens() {
        optColour = new Color(Color.WHITE);
        playColour = new Color(Color.WHITE);
        exitColour = new Color(Color.WHITE);
        playCoordinates = new Rectangle(Main.WIDTH / 2 - font.getBounds(play).width / 2, 210 - font.getCapHeight(),
                font.getBounds(play).width, font.getBounds(play).height);
        optionsCoordinates = new Rectangle(Main.WIDTH / 2 - font.getBounds(opt).width / 2, 140 - font.getCapHeight(),
                font.getBounds(opt).width, font.getBounds(opt).height);
        exitCoordinates = new Rectangle(Main.WIDTH / 2 - font.getBounds(exit).width / 2, 70 - font.getCapHeight(),
                font.getBounds(exit).width, font.getBounds(exit).height);
    }

    private void createPTS() {
        sprite = new Sprite[4];
        sprite[0] = new Sprite(Main.megaTexture, 1, 135, 48, 32);
        sprite[1] = new Sprite(Main.megaTexture, 2, 98, 44, 32);
        sprite[2] = new Sprite(Main.megaTexture, 1, 60, 32, 32);
        sprite[3] = new Sprite(Main.megaTexture, 1, 1, 124, 53);
        sprite[3].setScale(0.5f);
    }

    private void createOptionTokens() {
        selectBox = new SelectBox(new String[] { "800x600", "1024x768", "1280x1024", "1366x768", "1680x1050" }, skin);
        selectBox.setSelection(Main.pref.getSelection());
        selectBox.setSelectionListener(new SelectionListener() {
            public void selected(Actor actor, int index, String value) {
                Main.pref.setSelection(index);
            }
        });
        fsChecker = new CheckBox("Fullscreen", skin);
        fsChecker.setChecked(Main.pref.isFullScreen());
        vsyncChecker = new CheckBox("Vscync", skin);
        vsyncChecker.setChecked(Main.pref.getVsync());
        showFPS = new CheckBox("Show FPS", skin);
        showFPS.setChecked(Main.pref.showFPS);
        selectBox.validate();
        fsChecker.validate();
        vsyncChecker.validate();
        stage.addActor(fsChecker);
        stage.addActor(selectBox);
        stage.addActor(vsyncChecker);
        stage.addActor(showFPS);

    }

    @Override
    // Action listeners and state changers for the buttons
    public void update(float delta) {
        updateTokens();
        mouseY = Gdx.graphics.getHeight() - Gdx.input.getY();
        mouseX = Gdx.input.getX();
        if (optionsCoordinates.contains(mouseX, mouseY)) {
            optColour.set(Color.GREEN);
            if (!options && canSelect) {
                options = true;
            } else if (options && canSelect) {
                Main.pref.setFullScreen(fsChecker.isChecked());
                Main.pref.setVsync(vsyncChecker.isChecked());
                Main.pref.setShowFps(showFPS.isChecked());
                Main.pref.updateCFG();

                options = false;
            }
        } else {
            optColour.set(Color.WHITE);
        }
        if (options) {
            options = !Gdx.input.isKeyPressed(Keys.ESCAPE);
        } else {

            if (!options && playCoordinates.contains(mouseX, mouseY)) {
                playColour.set(Color.GREEN);
                if (!options && canSelect) {
                    isDone = true;
                }
            } else {
                playColour.set(Color.WHITE);
            }
            if (!options && exitCoordinates.contains(mouseX, mouseY)) {
                exitColour.set(Color.GREEN);
                if (!options && canSelect) {
                    Gdx.app.exit();
                }

            } else {
                exitColour.set(Color.WHITE);
            }
        }
        canSelect = false;
    }

    @Override
    public void draw(float delta) {
        camera.setToOrtho(false, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
        camera.update();
        spriteBatch.setProjectionMatrix(camera.combined);
        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        drawBackground();

        if (options) {
            stage.setViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false);
            stage.draw();
            spriteBatch.begin();
            font.setColor(Color.WHITE);
            font.draw(spriteBatch, "RECORD IS " + Main.pref.getRecord(),
                    Gdx.graphics.getWidth() / 2f - font.getBounds("RECORD IS " + Main.pref.getRecord()).width / 2f,
                    Gdx.graphics.getHeight() / 2f);
            font.setColor(optColour);
            font.draw(spriteBatch, "BACK", Gdx.graphics.getWidth() / 2f - font.getBounds("BACK").width / 2f, 140);
            spriteBatch.end();
        } else {
            spriteBatch.begin();
            drawPTS();
            font.setColor(playColour);
            font.draw(spriteBatch, play, Gdx.graphics.getWidth() / 2f - font.getBounds(play).width / 2f, 210);
            font.setColor(optColour);
            font.draw(spriteBatch, opt, Gdx.graphics.getWidth() / 2f - font.getBounds(opt).width / 2f, 140);
            font.setColor(exitColour);
            font.draw(spriteBatch, exit, Gdx.graphics.getWidth() / 2f - font.getBounds(exit).width / 2f, 70);
            spriteBatch.end();
        }
    }

    private void updateTokens() {
        playCoordinates.x = Gdx.graphics.getWidth() / 2f - font.getBounds(play).width / 2f;
        optionsCoordinates.x = Gdx.graphics.getWidth() / 2f - font.getBounds(opt).width / 2f;
        exitCoordinates.x = Gdx.graphics.getWidth() / 2f - font.getBounds(exit).width / 2f;
        sprite[0].setPosition(Gdx.graphics.getWidth() / 2f - 130, Gdx.graphics.getHeight() / 2f + 65);
        sprite[1].setPosition(Gdx.graphics.getWidth() / 2f - 127, Gdx.graphics.getHeight() / 2f + 15);
        sprite[2].setPosition(Gdx.graphics.getWidth() / 2f - 122, Gdx.graphics.getHeight() / 2f - 35);
        sprite[3].setPosition(Gdx.graphics.getWidth() / 2f - 168, Gdx.graphics.getHeight() / 2f - 95);
        selectBox.x = Gdx.graphics.getWidth() - 200;
        selectBox.y = stage.centerY();
        fsChecker.x = Gdx.graphics.getWidth() - 200;
        fsChecker.y = stage.centerY() + 50;
        vsyncChecker.x = Gdx.graphics.getWidth() - 200;
        vsyncChecker.y = stage.centerY() + 75;
        showFPS.x = Gdx.graphics.getWidth() - 200;
        showFPS.y = stage.centerY() + 100;

    }

    private void drawPTS() {
        sprite[0].draw(spriteBatch);
        sprite[1].draw(spriteBatch);
        sprite[2].draw(spriteBatch);
        sprite[3].draw(spriteBatch);
        font.setColor(Color.WHITE);
        font.draw(spriteBatch, "= 10 PTS", Gdx.graphics.getWidth() / 2 - 60, Gdx.graphics.getHeight() / 2 + 95);
        font.draw(spriteBatch, "= 20 PTS", Gdx.graphics.getWidth() / 2 - 60, Gdx.graphics.getHeight() / 2 + 45);
        font.draw(spriteBatch, "= 40 PTS", Gdx.graphics.getWidth() / 2 - 60, Gdx.graphics.getHeight() / 2 - 5);
        font.draw(spriteBatch, "= ??? PTS", Gdx.graphics.getWidth() / 2 - 60, Gdx.graphics.getHeight() / 2 - 55);
    }

    private void drawBackground() {
        spriteBatch.begin();
        spriteBatch.disableBlending();
        spriteBatch.setColor(Color.WHITE);
        spriteBatch.draw(Main.backgroundTexture, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
        spriteBatch.enableBlending();

        logo.setPosition(Gdx.graphics.getWidth() / 2 - 180, Gdx.graphics.getHeight() - 200);
        logo.draw(spriteBatch);

        spriteBatch.end();

    }

    @Override
    public boolean isDone() {
        return isDone;
    }

    @Override
    public void dispose() {
        spriteBatch.dispose();
        font.dispose();
    }
}
